package com.mikao.service.impl;


import com.mikao.dao.*;
import com.mikao.dto.bo.ReqDataTableDto;
import com.mikao.dto.bo.SysRoleForm;
import com.mikao.dto.vo.RoleNameDto;
import com.mikao.dto.vo.SysRoleDto;
import com.mikao.dto.vo.RspDataTableDto;
import com.mikao.entity.SysPermission;
import com.mikao.entity.SysRole;
import com.mikao.entity.SysRolePermission;
import com.mikao.service.SysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author KennyDavid
 */

@Service
public class SysRoleServiceImpl implements SysRoleService {

    private final SysRoleDao sysRoleDao;
    private final SysRolePermissionDao sysRolePermissionDao;
    private final SysUserDao sysUserDao;
    private final SysPermissionDao sysPermissionDao;
    private final SysUserDao userDao;
    private final SysPermissionDao permissionDao;


    public SysRoleServiceImpl(SysRoleDao sysRoleDao, SysRolePermissionDao sysRolePermissionDao, SysUserDao sysUserDao, SysPermissionDao sysPermissionDao, SysUserDao userDao, SysPermissionDao permissionDao) {
        this.sysRoleDao = sysRoleDao;
        this.sysRolePermissionDao = sysRolePermissionDao;
        this.sysUserDao = sysUserDao;
        this.sysPermissionDao = sysPermissionDao;
        this.userDao = userDao;
        this.permissionDao = permissionDao;
    }


    @Override
    public List<RoleNameDto> getRoleList() {
        List<RoleNameDto> dtos = new ArrayList<>();
        List<SysRole> list = sysRoleDao.findAll();
        RoleNameDto roleDto;
        for (SysRole sysRole : list) {
            roleDto = new RoleNameDto();
            roleDto.setId(sysRole.getId());
            roleDto.setRoleName(sysRole.getRoleName());
            dtos.add(roleDto);
        }
        return dtos;

    }


    @Override
    public RspDataTableDto<SysRoleDto> getRolePage(ReqDataTableDto dataTableDTO) {
        Page<SysRole> page = sysRoleDao.findAll(new PageRequest(dataTableDTO.getPage(), dataTableDTO.getLength(),
                new Sort(Sort.Direction.DESC, "createTime")));

        List<SysRoleDto> dtos = new ArrayList<>();
        SysRoleDto roleDto;
        SysRolePermission sysRolePermission;
        Set<String> permissions;
        for (SysRole sysRole : page.getContent()) {
            roleDto = new SysRoleDto();
            sysRolePermission = sysRolePermissionDao.findByRoleId(sysRole.getId());
            permissions = new HashSet<>();
            roleDto.setId(sysRole.getId());
            roleDto.setRoleName(sysRole.getRoleName());
            roleDto.setPermissionId(sysRolePermission.getPermissionIds());
            for (String str : sysRolePermission.getPermissionIds().split(",")) {
                if (!ObjectUtils.isEmpty(sysPermissionDao.findOne(Long.valueOf(str)))) {
                    permissions.add(sysPermissionDao.findOne(Long.valueOf(str)).getName());
                }
            }
            roleDto.setPermissions(org.springframework.util.StringUtils.collectionToDelimitedString(permissions, ","));
            roleDto.setCreateTime(sysRole.getCreateTime());
            dtos.add(roleDto);
        }
        return new RspDataTableDto<>(dataTableDTO.getDraw(), page.getTotalElements(), dtos);
    }


    @Override
    @Transactional(rollbackOn = Exception.class)
    public Boolean deleteRole(Long roleId) {
        long sysUserCount = sysUserDao.countByRoleId(roleId);
        if (sysUserCount != 0) {
            return false;
        }
        sysRoleDao.delete(roleId);

        SysRolePermission byRoleId = sysRolePermissionDao.findByRoleId(roleId);
        sysRolePermissionDao.delete(byRoleId);
        return true;
    }


    @Override
    @Transactional(rollbackOn = Exception.class)
    public void saveRole(SysRoleForm sysRoleForm) {
        SysRole sysRole;
        if (sysRoleForm.getId() == null) {
            sysRole = new SysRole();
        } else {
            sysRole = sysRoleDao.findOne(sysRoleForm.getId());
            sysRole.setRoleName(sysRoleForm.getRoleName());
            sysRoleDao.saveAndFlush(sysRole);
        }

        Set<SysPermission> permissions = new HashSet<>();
        if (sysRoleForm.getPermissionId() != null) {
            for (Long permissionId : sysRoleForm.getPermissionId()) {
                SysPermission permission = permissionDao.findOne(permissionId);
                permissions.add(permission);
            }
            sysRole.setRoleName(sysRoleForm.getRoleName());
        } else {
            sysRole.setRoleName(null);
        }
        sysRole.setStatus(true);
        sysRoleDao.saveAndFlush(sysRole);

        String str = "";
        SysRolePermission sysRolePermission = sysRolePermissionDao.findByRoleId(sysRole.getId());
        if (!ObjectUtils.isEmpty(sysRolePermission)) {
            for (SysPermission sysPermission : permissions) {
                str += sysPermission.getId() + ",";
            }

            sysRolePermission.setPermissionIds(str.substring(0, str.length() - 1));
            sysRolePermissionDao.saveAndFlush(sysRolePermission);
        } else {
            sysRolePermission = new SysRolePermission();
            for (SysPermission sysPermission : permissions) {
                str += sysPermission.getId() + ",";
            }

            sysRolePermission.setPermissionIds(str.substring(0, str.length() - 1));
            sysRolePermission.setRoleId(sysRole.getId());

            sysRolePermissionDao.saveAndFlush(sysRolePermission);
        }
    }


    @Override
    public Boolean isRoleExist(String role) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleName(role);
        Example<SysRole> example = Example.of(sysRole);
        return sysRoleDao.findOne(example) == null;
    }

/*

    @Override
    public List<SysRoleDto> getUserRoleList() {
        List<SysRoleDto> dtos = new ArrayList<>();
        List<SysRole> list = sysRoleDao.findUserRoleList();
        SysRoleDto roleDto;
        for (SysRole sysRole : list) {
            roleDto = new SysRoleDto();
            roleDto.setId(sysRole.getId());
            roleDto.setRoleName(sysRole.getRoleName());
            dtos.add(roleDto);
        }
        return dtos;

    }
*/


}
